﻿
using System;
using System.Text;
using System.Web;

using Microsoft.VisualStudio.TestTools.UnitTesting;

using MvcScriptManager.UniqueKeyEncoding;

namespace MvcScriptManager.Tests.UniqueKeyEncoding
{
	/// <summary>
	/// Tests the <see cref="UniqueKeyTwoWayEncoding"/> class
	/// </summary>
	[TestClass]
	public class UniqueKeyTwoWayEncodingTests
	{
		/// <summary>
		/// Gets or sets the test context which provides
		/// information about and functionality for the current test run.
		/// </summary>
		public TestContext TestContext { get; set; }

		private UniqueKeyTwoWayEncoding encoder;

		private HttpContext dummyHttpContext;

		[TestInitialize]
		public void Initialize()
		{
			encoder = new UniqueKeyTwoWayEncoding();

			HttpRequest httpRequest = new HttpRequest(null, "http://localhost/", null);
			HttpResponse httpResponse = new HttpResponse(null);
			dummyHttpContext = new HttpContext(httpRequest, httpResponse);
		}

		[TestMethod]
		public void TestEncodeUniqueKey()
		{
			ScriptReference reference = new ScriptReference
			                            	{
			                            			Path = "/content/sample.js",
			                            			EnableCrunching = true,
			                            			ResourceAssembly = "SampleWeb",
			                            			ResourceName = "SampleWeb.Sample",
			                            			ResourceTypeName = "Sample"
			                            	};

			string uniqueKey = encoder.EncodeUniqueKey(reference, dummyHttpContext);

			Assert.IsNotNull(uniqueKey);

			const string expectedPlainText = "/CONTENT/SAMPLE.JS|Y|SampleWeb|SampleWeb.Sample|Sample";
			string expectedBase64Text = Convert.ToBase64String(Encoding.ASCII.GetBytes(expectedPlainText));

			Assert.AreEqual(expectedBase64Text, uniqueKey);
		}

		[TestMethod]
		public void TestEncodeUniqueKeyWithNoCrunching()
		{
			ScriptReference reference = new ScriptReference
			{
				Path = "/content/sample.js",
				EnableCrunching = false,
				ResourceAssembly = "SampleWeb",
				ResourceName = "SampleWeb.Sample",
				ResourceTypeName = "Sample"
			};

			string uniqueKey = encoder.EncodeUniqueKey(reference, dummyHttpContext);

			Assert.IsNotNull(uniqueKey);

			const string expectedPlainText = "/CONTENT/SAMPLE.JS|N|SampleWeb|SampleWeb.Sample|Sample";
			string expectedBase64Text = Convert.ToBase64String(Encoding.ASCII.GetBytes(expectedPlainText));

			Assert.AreEqual(expectedBase64Text, uniqueKey);
		}

		[TestMethod]
		public void TestEncodeUniqueKeyWithNoLocalization()
		{
			ScriptReference reference = new ScriptReference
			{
				Path = "/content/sample.js",
				EnableCrunching = false
			};

			string uniqueKey = encoder.EncodeUniqueKey(reference, dummyHttpContext);

			Assert.IsNotNull(uniqueKey);

			const string expectedPlainText = "/CONTENT/SAMPLE.JS|N|||";
			string expectedBase64Text = Convert.ToBase64String(Encoding.ASCII.GetBytes(expectedPlainText));

			Assert.AreEqual(expectedBase64Text, uniqueKey);
		}

		/// <summary>
		/// Tests that encoding a unique key, then decoding it returns the same script reference
		/// </summary>
		[TestMethod]
		public void TestEncodeDecodeReturnsSameResult()
		{
			ScriptReference reference = new ScriptReference
			{
				Path = "/content/encodedecodetest.js",
				EnableCrunching = false,
				ResourceAssembly = "SampleWeb",
				ResourceName = "SampleWeb.Sample",
				ResourceTypeName = "Sample"
			};

			string uniqueKey = encoder.EncodeUniqueKey(reference, dummyHttpContext);

			Assert.IsNotNull(uniqueKey);

			ScriptReference actual = encoder.DecodeUniqueKey(uniqueKey, dummyHttpContext);

			Assert.IsNotNull(actual);

			Assert.AreEqual(reference.Path, actual.Path);
			Assert.AreEqual(reference.EnableCrunching, actual.EnableCrunching);
			Assert.AreEqual(reference.ResourceAssembly, actual.ResourceAssembly);
			Assert.AreEqual(reference.ResourceName, actual.ResourceName);
			Assert.AreEqual(reference.ResourceTypeName, actual.ResourceTypeName);
		}

		[TestMethod]
		public void TestDecodeUniqueKey()
		{
			const string uniqueKey = "/CONTENT/SAMPLE.JS|Y|SampleWeb|SampleWeb.Sample|Sample";
			string base64UniqueKey = Convert.ToBase64String(Encoding.ASCII.GetBytes(uniqueKey));

			ScriptReference reference = encoder.DecodeUniqueKey(base64UniqueKey, dummyHttpContext);

			Assert.IsNotNull(reference);

			Assert.AreEqual("/CONTENT/SAMPLE.JS", reference.Path);
			Assert.IsTrue(reference.EnableCrunching, "EnableCrunching");
			Assert.AreEqual("SampleWeb", reference.ResourceAssembly);
			Assert.AreEqual("SampleWeb.Sample", reference.ResourceName);
			Assert.AreEqual("Sample", reference.ResourceTypeName);
		}
	}
}